import React, { useEffect, useState } from 'react';
import {
  Box,
  Grid,
  GridItem,
  MainButton,
  makeToast,
  Modal,
  ModalHeader,
  Text,
  UsageCard,
} from '@nova-hf/ui';
import { CONTRACT_ITEMS } from 'beta/graphql/queries/Contracts';
import { serviceStatusColorIconMap } from 'beta/utils/helpers';
import { useRouter } from 'next/router';
import {
  ContractStatus,
  ContractUsageInfo,
  ContractUsagePayload,
  ServiceStatus,
  useContractItemsQuery,
  useContractUsageLazyQuery,
  useDeactivateContractItemMutation,
} from 'typings/graphql';
import { useTranslation } from 'utils/i18n';

type ActiveContractItemsProps = {
  color?: string;
};

export const ActiveContractItems = ({ color }: ActiveContractItemsProps) => {
  const { t } = useTranslation('service');
  const COLOR = color ?? 'pink';
  const router = useRouter();
  const serviceId = typeof router?.query?.serviceId === 'string' ? router?.query?.serviceId : '';
  const customerId = typeof router?.query?.customerId === 'string' ? router?.query?.customerId : '';
  const [selectedContractItemId, setSelectedContractItemId] = useState<string>();
  const [contractVariantId, setContractVariantId] = useState<string>();

  const {
    data: contractData,
    loading: contractLoading,
    error: contractError,
  } = useContractItemsQuery({
    variables: {
      input: {
        serviceId,
        customerId,
      },
    },
    skip: !serviceId || !customerId,
  });

  const contract = contractData?.contracts.contracts.find(
    (contract) =>
      contract.status === ContractStatus.Active || contract.status === ContractStatus.Pending,
  );

  const [getContractUsage, { loading: loadingUsage, data: usageData }] =
    useContractUsageLazyQuery();

  const [deactivateContractItem, { loading: loadingDeactivate }] =
    useDeactivateContractItemMutation({
      refetchQueries: [
        {
          query: CONTRACT_ITEMS,
          variables: {
            input: {
              serviceId: (router.query.serviceId as string) ?? '',
            },
          },
        },
      ],
      awaitRefetchQueries: true,
    });

  useEffect(() => {
    if (contractData?.contracts.contracts.length === 1) {
      const contract = contractData.contracts.contracts[0];
      const variantId: string = contract.variant?.id ?? '';
      setContractVariantId(variantId);
      getContractUsage({
        variables: {
          input: { id: contract.id, serviceId: (router.query.serviceId as string) ?? '' },
        },
      });
    }
  }, [contractData]);

  const handleDeactivateContractItem = async () => {
    try {
      await deactivateContractItem({
        variables: {
          input: {
            id: contract?.id ?? '',
            contractItemId: selectedContractItemId ?? '',
          },
        },
      });
      makeToast.success(
        t('activeContractItems.successTitle'),
        t('activeContractItems.successDescription'),
      );

      setSelectedContractItemId(undefined);
    } catch (error) {
      if (error instanceof Error) {
        makeToast.danger(t('activeContractItems.errorTitle'), error.message);
      }
    }
  };

  const actitveContractItemServices = contractData?.contracts.contracts.length
    ? contract?.contractItems.filter(
        (contractItem) => contractItem?.status?.toLowerCase() === 'active',
      )
    : undefined;

  const isAlltSaman = contractData?.contracts.contracts.length
    ? contract?.variant?.id.includes('allt-saman')
      ? true
      : undefined
    : false;

  const activeContractItemServices = isAlltSaman
    ? actitveContractItemServices?.filter((contractItem) => contractItem?.service?.id === serviceId)
    : actitveContractItemServices;

  if (contractError) {
    return (
      <Box>
        <Text variant="h6" marginBottom={4}>
          {t('activeContractItems.title')}
        </Text>
        <Text variant="pMediumBold" marginBottom={4}>
          {t('activeContractItems.error')}
        </Text>
      </Box>
    );
  }

  if (!actitveContractItemServices?.length) {
    return null;
  }

  return (
    <>
      {(contractLoading || actitveContractItemServices?.length) && (
        <Box>
          <Text variant="h6" marginBottom={4}>
            {t('activeContractItems.title')}
          </Text>
          <Grid gridTemplate={2}>
            {contractLoading
              ? Array.from({ length: 2 }).map((_, i) => (
                  <UsageCard
                    key={i}
                    title=""
                    height="30"
                    width="50%"
                    usage={{
                      remaning: {
                        amount: '',
                      },
                      total: {
                        amount: '',
                      },
                      used: {
                        amount: '',
                      },
                    }}
                    progressBar={{
                      percentage: 0,
                      thickness: 1,
                    }}
                    price={{
                      amount: '',
                    }}
                    isLoading
                  />
                ))
              : activeContractItemServices?.map((contractItem) => {
                  const statusColor = serviceStatusColorIconMap(
                    (contractItem?.status as ServiceStatus) ?? '',
                  ).color;

                  const contractItemId: string = contractItem.id;
                  let usage: ContractUsageInfo | undefined;
                  if (
                    usageData?.contractUsage?.length &&
                    usageData.contractUsage[0]?.__typename &&
                    usageData.contractUsage[0].__typename === 'ContractUsagePayload'
                  ) {
                    const usageInfoArr = usageData.contractUsage as ContractUsagePayload[];

                    usage =
                      usageInfoArr
                        .find((usageInfo) => usageInfo.contractItemId === contractItemId)
                        ?.usageInfo?.find((usageInfoItem) => usageInfoItem?.isPrimary === true) ??
                      undefined;
                  }

                  const remainingPercentage = () => {
                    if (usage?.infinite) return 100;
                    if (usage?.included?.amount) {
                      return (
                        100 -
                        Math.round(
                          ((usage?.remaining?.amount ?? 0) / (usage?.included?.amount ?? 0)) * 100,
                        )
                      );
                    } else return 0;
                  };

                  return (
                    <GridItem key={contractItemId} gridColumn={{ sm: 'span2', lg: 'span1' }}>
                      <UsageCard
                        key={contractItemId}
                        width="50%"
                        color={loadingUsage ? 'grey400' : COLOR}
                        price={{
                          amount:
                            contractItem.variant?.monthlyCharge ?? contractItem.variant?.price ?? 0,
                          ...(contractItem.variant?.monthlyCharge && { unit: '/MÁN' }),
                        }}
                        progressBar={{
                          percentage: loadingUsage ? 100 : remainingPercentage(),
                          thickness: 1,
                        }}
                        status={{
                          package: {
                            amount: ' ',
                            description: ' ',
                            unit: ' ',
                          },
                          pill: {
                            color: loadingUsage ? 'grey400' : statusColor,
                            text: loadingUsage ? '...' : contractItem?.status ?? '',
                          },
                        }}
                        title={
                          contractItem.variant?.name ?? contractItem.variant?.productName ?? ''
                        }
                        usage={{
                          remaning: {
                            amount: loadingUsage ? ' ' : usage?.remaining?.amount ?? 0,
                            description: loadingUsage ? ' ' : t('activeContractItems.left'),
                            unit: loadingUsage ? ' ' : usage?.remaining?.unit ?? '',
                            isinfinite: loadingUsage ? ' ' : usage?.infinite,
                          },
                          total: {
                            amount: loadingUsage ? ' ' : usage?.included?.amount ?? 0,
                            unit: loadingUsage ? ' ' : usage?.included?.unit ?? '',
                            isinfinite: loadingUsage ? ' ' : usage?.infinite,
                          },
                          used: {
                            amount: loadingUsage
                              ? ' '
                              : (
                                  (usage?.included?.amount ?? 0) - (usage?.remaining?.amount ?? 0)
                                ).toFixed(1) ?? 0,
                            description: loadingUsage ? ' ' : t('activeContractItems.used'),
                            unit: loadingUsage ? ' ' : usage?.included?.unit ?? '',
                          },
                        }}
                        {...(contractItem.variantId !== contractVariantId && {
                          menu: {
                            menuLabel: t('activeContractItems.menu.label'),
                            menuItems: [
                              {
                                text: t('activeContractItems.menu.deactivate'),
                                onClick: () => setSelectedContractItemId(contractItemId),
                              },
                            ],
                          },
                        })}
                        withBorder
                      />
                    </GridItem>
                  );
                })}
          </Grid>
        </Box>
      )}
      <Modal
        ariaLabel={t('activeContractItems.modal.ariaLabel')}
        onVisibilityChange={(isVisible) =>
          !isVisible
            ? setSelectedContractItemId(undefined)
            : setSelectedContractItemId(selectedContractItemId)
        }
        isVisible={!!selectedContractItemId}
      >
        <Box display="flex" flexDirection="column" width="100%">
          <ModalHeader
            title={t('activeContractItems.modal.title')}
            eyebrow={t('activeContractItems.modal.eyebrow')}
            color="warning"
            icon="mobileGlobe"
          />
          <Box marginY={5} flexGrow={1}>
            {t('activeContractItems.modal.description')}
          </Box>
          <Box display="flex" flexDirection={['column', 'row', 'row']} gap={4} width="100%">
            <MainButton
              text={t('activeContractItems.modal.cancelButton')}
              colorScheme="white"
              dottedShadow="none"
              isDisabled={loadingDeactivate}
              onClick={() => setSelectedContractItemId(undefined)}
            />
            <MainButton
              text={t('activeContractItems.modal.ctaButton')}
              colorScheme="warning"
              dottedShadow="none"
              isLoading={loadingDeactivate}
              onClick={() => handleDeactivateContractItem()}
            />
          </Box>
        </Box>
      </Modal>
    </>
  );
};
